﻿using System;
using System.Net;
using System.IO;
using Hydra.Shell.Enumerations;

namespace Hydra.Shell.Attributes
{
    [AttributeUsage(AttributeTargets.Class)]
    public abstract class RegistrationAttribute : Attribute
    {
        protected RegistrationAttribute()
        {
        }

        protected string GetPackageRegKeyPath(Guid package)
        {
            return string.Format(@"Packages\{0}", new object[] { package.ToString("B") });
        }

        public abstract void Register(RegistrationContext context);
        public abstract void Unregister(RegistrationContext context);

        public object TypeId
        {
            get
            {
                Type type = base.GetType();
                bool allowMultiple = false;
                object[] customAttributes = type.GetCustomAttributes(typeof(AttributeUsageAttribute), true);
                int index = 0;
                while (index < customAttributes.Length)
                {
                    AttributeUsageAttribute attribute = (AttributeUsageAttribute)customAttributes[index];
                    allowMultiple = attribute.AllowMultiple;
                    break;
                }
                if (allowMultiple)
                {
                    return this;
                }
                return type;
            }
        }

        public abstract class Key : IDisposable
        {
            protected Key()
            {
            }

            public abstract void Close();
            public abstract RegistrationAttribute.Key CreateSubkey(string name);
            public abstract void SetValue(string valueName, object value);
            void IDisposable.Dispose()
            {
                this.Close();
            }
        }

        public abstract class RegistrationContext
        {
            protected RegistrationContext()
            {
            }

            public abstract RegistrationAttribute.Key CreateKey(string name);
            public abstract string EscapePath(string str);
            public abstract void RemoveKey(string name);
            public abstract void RemoveKeyIfEmpty(string name);
            public abstract void RemoveValue(string keyname, string valuename);

            public abstract string CodeBase { get; }

            public abstract string ComponentPath { get; }

            public abstract Type ComponentType { get; }

            public abstract string InprocServerPath { get; }

            public abstract TextWriter Log { get; }

            public abstract RegistrationMethod RegistrationMethod { get; }

            public abstract string RootFolder { get; }
        }
    }
}
